﻿using System;
using System.Collections.Generic;
using System.Text;

namespace 设计模式01
{
    /// <summary>
    /// 适配器模式
    /// </summary>
    public class Adapter
    {
    }

    #region 类的适配器模式实现
    ///// <summary>
    ///// 三个孔的插头，也就是适配器模式中的目标角色
    ///// </summary>
    //public interface IThreeHole
    //{
    //    void Request();
    //}

    ///// <summary>
    ///// 两个孔的插头，源角色--需要适配的类
    ///// </summary>
    //public abstract class TwoHole
    //{
    //    public void SpecificRequest()
    //    {
    //        Console.WriteLine("我是两个孔的插头");
    //    }

    //}

    ///// <summary>
    ///// 适配器类，接口要放在类的后面
    ///// 适配器提供了三个孔插头的行为，但其本质是调用两个孔插头的方法
    ///// </summary>
    //public class PowerAdapter : TwoHole, IThreeHole
    //{
    //    public void Request()
    //    {
    //        this.SpecificRequest();
    //    }
    //}
    #endregion

    #region 对象的适配器模式实现

    /// <summary>
    /// 三个孔的插头，也就是适配器模式中的目标角色
    /// </summary>
    public class ThreeHole
    {
        /// <summary>
        /// 客户端需要的方法
        /// </summary>
        public virtual void Request()
        {
            // 可以把一般实现放在这里
        }
    }

    /// <summary>
    /// 两个孔的插头，源角色--需要适配的类
    /// </summary>
    public class TwoHole
    {
        public void SpecificRequest()
        {
            Console.WriteLine("我是两个孔的插头");
        }
    }

    /// <summary>
    /// 适配器类，这里适配器没有TwoHole类，
    /// 而是引用了TwoHole对象，所以是对象的适配器模式的实现
    /// </summary>
    public class PowerAdapter : ThreeHole
    {
        public TwoHole TwoHoleAdaptee = new TwoHole();
        public override void Request()
        {
            TwoHoleAdaptee.SpecificRequest();
        }
    }

    /* 
     * 适配器模式的优缺点：
     * 【类的适配器模式】
     * 1. 优点：
     *      可以在不修改原有代码的基础上来复用现有类，很好地符合“开闭原则”
     *      可以重新定义Adaptee的部分行为，因为在类适配器模式中，Adapter是Adaptee的子类
     *      仅仅引入了一个对象，并不需要额外的字段来引用Adaptee实例
     * 2. 缺点：
     *      用一个具体的Adapter类对Adaptee和Target进行匹配，当如果想要匹配一个类以及所有它的子类的时候，类的适配器模式就不能胜任了，因为类的适配器模式中没有引入Adaptee的实例，只调用this.SpecificRequest方法并不能去调用它对应子类的SpecificRequest方法。
     *      采用了多继承的实现方式，带来了不良的高耦合。
     */

    #endregion
}
